"""
后台任务服务
负责定时刷新缓存和数据聚合
"""

import asyncio

from app.service.dashboard_service import get_dashboard_service
from common.database import get_db_dependency
from common.logger import create_logger

logger = create_logger(__name__)


class BackgroundTaskService:
	"""后台任务服务"""

	def __init__(self):
		self.dashboard_service = get_dashboard_service()
		self.running = False
		self.tasks = []

	async def start_background_tasks(self):
		"""启动后台任务"""
		if self.running:
			logger.warning("后台任务已在运行中")
			return

		self.running = True
		logger.info("启动后台任务")

		# 启动各种定时任务
		self.tasks = [
			asyncio.create_task(self._kpi_refresh_task()),
			asyncio.create_task(self._station_load_refresh_task()),
			asyncio.create_task(self._alert_refresh_task()),
		]

		logger.info(f"已启动 {len(self.tasks)} 个后台任务")

	async def stop_background_tasks(self):
		"""停止后台任务"""
		if not self.running:
			return

		self.running = False
		logger.info("停止后台任务")

		# 取消所有任务
		for task in self.tasks:
			if not task.done():
				task.cancel()

		# 等待任务完成
		if self.tasks:
			await asyncio.gather(*self.tasks, return_exceptions=True)

		self.tasks.clear()
		logger.info("所有后台任务已停止")

	async def _kpi_refresh_task(self):
		"""KPI指标刷新任务 - 每5分钟执行一次"""
		task_name = "KPI指标刷新"
		interval = 300  # 5分钟

		logger.info(f"启动{task_name}任务，间隔: {interval}秒")

		while self.running:
			try:
				# 获取数据库连接
				db_gen = get_db_dependency()
				db = None
				
				try:
					db = next(db_gen)
					# 刷新KPI缓存
					await self.dashboard_service.get_kpi_metrics(db, force_refresh=True)
					logger.debug(f"{task_name}执行成功")

				finally:
					if db is not None:
						try:
							db.close()
						except Exception as close_error:
							logger.error(f"关闭数据库连接失败: {close_error}")

				# 等待下次执行
				await asyncio.sleep(interval)

			except asyncio.CancelledError:
				logger.info(f"{task_name}任务被取消")
				break
			except Exception as e:
				logger.error(f"{task_name}任务执行失败: {e}")
				# 出错后等待较短时间重试
				await asyncio.sleep(60)

	async def _station_load_refresh_task(self):
		"""台区负荷刷新任务 - 每1分钟执行一次"""
		task_name = "台区负荷刷新"
		interval = 60  # 1分钟

		logger.info(f"启动{task_name}任务，间隔: {interval}秒")

		while self.running:
			try:
				# 获取数据库连接
				db_gen = get_db_dependency()
				db = None
				
				try:
					db = next(db_gen)
					# 刷新高负载台区缓存
					await self.dashboard_service.get_high_load_stations(db, force_refresh=True)
					logger.debug(f"{task_name}执行成功")

				finally:
					if db is not None:
						try:
							db.close()
						except Exception as close_error:
							logger.error(f"关闭数据库连接失败: {close_error}")

				# 等待下次执行
				await asyncio.sleep(interval)

			except asyncio.CancelledError:
				logger.info(f"{task_name}任务被取消")
				break
			except Exception as e:
				logger.error(f"{task_name}任务执行失败: {e}")
				# 出错后等待较短时间重试
				await asyncio.sleep(30)

	async def _alert_refresh_task(self):
		"""告警数据刷新任务 - 每30秒执行一次"""
		task_name = "告警数据刷新"
		interval = 30  # 30秒

		logger.info(f"启动{task_name}任务，间隔: {interval}秒")

		while self.running:
			try:
				# 获取数据库连接
				db_gen = get_db_dependency()
				db = None
				
				try:
					db = next(db_gen)
					# 刷新告警相关缓存并检查告警状态变化
					await asyncio.gather(
						self.dashboard_service.get_recent_alerts(db, force_refresh=True),
						self.dashboard_service.get_alarm_statistics(db, force_refresh=True),
						self.dashboard_service.check_and_push_alarm_changes(db),  # 新增告警状态检查
						return_exceptions=True
					)
					logger.debug(f"{task_name}执行成功")

				finally:
					if db is not None:
						try:
							db.close()
						except Exception as close_error:
							logger.error(f"关闭数据库连接失败: {close_error}")

				# 等待下次执行
				await asyncio.sleep(interval)

			except asyncio.CancelledError:
				logger.info(f"{task_name}任务被取消")
				break
			except Exception as e:
				logger.error(f"{task_name}任务执行失败: {e}")
				# 出错后等待较短时间重试
				await asyncio.sleep(15)


# 全局后台任务服务实例
background_service = BackgroundTaskService()


async def start_background_tasks():
	"""启动后台任务的便捷函数"""
	await background_service.start_background_tasks()


async def stop_background_tasks():
	"""停止后台任务的便捷函数"""
	await background_service.stop_background_tasks()


def get_background_service() -> BackgroundTaskService:
	"""获取后台任务服务实例"""
	return background_service
